
#ifndef GKT_I2C_DEFINES_H
#define GKT_I2C_DEFINES_H

#include "gkt_types.h"
//#include "gkt_board.h"
#include "gkt_defines.h"
#include "gkt_debug.h"
#include "gkt_os.h"
//#include "gkt_driver.h"


#define I2C_MASTER_ENABLE	1

/* I2C attrs */
/* pad */
//#define I2C_PAD_SCL		0
//#define I2C_PAD_SDA		1
//#define I2C_PAD_NUMS	2


/************************************************************
 * I2C attr -- START
 ***********************************************************/
typedef struct _i2c_attr {
	//gkt_device_base_attr_s	base_attr;
	//gkt_clkrst_desc_u	clkrst_desc;
	//gkt_padmux_desc_s	padmux_descs[I2C_PAD_NUMS];
	
	uint8_t slave_nums;		/* slave(CS#) nums of master */
} i2c_attr_s;

/*
 * features
 */
#define I2C_ATTR_SLAVE_NUMS_DEFINE(dev_id)	\
	.slave_nums = GKT_CONFIG_I2C##dev_id##_SLAVE_NUMS,


#define I2C_ATTR_DEFINE(dev_id)	\
	{	\
		I2C_ATTR_SLAVE_NUMS_DEFINE(dev_id)	\
	}

//GKT_DEVICE_ATTRS_DECLARE(i2c);



/*#define I2C_PADMUX_DESC(dev_id, pad_name)	\
	&GKT_DEVICE_ATTR(i2c, dev_id).padmux_descs[I2C_PAD_##pad_name]*/

/*
 * I2C_CLKRST_DESC
 */
/*#define I2C_CLKRST_DESC(dev_id)	\
	((gkt_clkrst_desc_u *)&GKT_DEVICE_ATTR(i2c, dev_id).clkrst_desc)*/

/*#define I2C_SLAVE_NUMS(dev_id)	\
	GKT_DEVICE_ATTR(i2c, dev_id).slave_nums*/

#define I2C_SLAVE_NUMS(dev_id)	\
	gc_i2c_attrs[dev_id].slave_nums



/*#define I2C_MST_PADMUX_DESCS(dev_id)	\
	GKT_DEVICE_ATTR(i2c, dev_id).mst_padmux_descs.common*/

extern i2c_attr_s gc_i2c_attrs[];


/************************************************************
 * I2C -- START
 ***********************************************************/
typedef struct _i2c_instance	i2c_instance_s;
typedef struct _i2c_opnode	i2c_opnode_s;

enum {
	I2C_OPNODE_STATE_IDLE = 0,
	I2C_OPNODE_STATE_OPENED,
	I2C_OPNODE_STATE_CONFIG,
	I2C_OPNODE_STATE_TRANSCEIVE,
	I2C_OPNODE_STATE_MAX
};

/*
 * i2c opnode
 */
struct _i2c_opnode {
	i2c_instance_s	*instance;

	uint8_t		id;
	uint8_t		state;
	uint16_t 	target_addr;
	uint32_t	addr_bits;
	uint32_t	speed;
	uint32_t	restart_enable;	
};

#define I2C_OPNODE_F_CSN_SOFT	(1U << 0)

#define I2C_MASTER_OPNODE_NUMS(dev_id)	\
	GKT_CONFIG_I2C##dev_id##_SLAVE_NUMS

#define I2C_SLAVE_OPNODE_NUMS(dev_id)	0

#define I2C_OPNODE_NUMS(dev_id)	\
	(I2C_MASTER_OPNODE_NUMS(dev_id) + I2C_SLAVE_OPNODE_NUMS(dev_id))

#define I2C_OPNODES_DEFINE	\
	i2c_opnode_s g_i2c_opnodes[GKT_CONFIG_I2C0_SLAVE_NUMS + GKT_CONFIG_I2C1_SLAVE_NUMS]
extern i2c_opnode_s g_i2c_opnodes[];

#define I2C_OPNODE(instance, opnode_id)	((instance)->opnodes + (opnode_id))

struct _i2c_instance {
	uint32_t	id;
	int	active_opnode_id;	/* opnode active id */

	i2c_opnode_s	*opnodes;
	gkt_semaphore_t active_semaphore;
	gkt_semaphore_t	finish_semaphore;

	uint8_t 	*send_buffer;
	uint32_t	send_size;
	uint32_t	send_buf_size_max;

	uint8_t		*receive_buffer;
	uint32_t	receive_total_size;
};

typedef struct _i2c {
	int	init;
	i2c_instance_s	instances[GKT_I2C_MAXNUMS];
} i2c_t;

#define I2C_DEFINE	\
	I2C_OPNODES_DEFINE;	\
	i2c_t g_i2c;
extern i2c_t g_i2c;

#define I2C_INSTANCE(dev_id)	(&g_i2c.instances[dev_id])
#define I2C_INSTANCE_DEVID(instance)	((instance) - g_i2c.instances)


/************************************************************
 * I2C -- END
 ***********************************************************/

#endif	/* I2C_DEFINES_H */


